CAP 理论回顾
在对比注册中心方案前,需要理解 CAP 理论。CAP 代表分布式系统的三个特性:
| 特性 | 说明 |
|---|---|
| Consistency(一致性) | 所有节点在同一时刻看到相同的数据 |
| Availability(可用性) | 每个请求都能得到非错误的响应 |
| Partition tolerance(分区容忍) | 网络分区时系统仍然运行 |
CAP 定理指出:分布式系统最多同时满足其中两个,无法三者兼顾。因为网络分区(P)是不可避免的,所以实际上只能在 CP(一致性 + 分区容忍)和 AP(可用性 + 分区容忍)之间选择。
CAP 不可能都取,只能取其中 2 个的原因:
- 如果 C 是第一需求,那么会影响 A 的性能,因为要数据同步,不然请求结果会有差异,但数据同步会消耗时间,期间可用性就会降低
- 如果 A 是第一需求,那么只要有一个服务在就能正常接受请求,但对于返回结果便不能保证,原因是分布式部署时数据一致的过程不可能像切线路那么快
- 如果同时满足一致性和可用性,那么分区容错就很难保证了,也就是单点,违背了分布式的核心
一致性协议算法
分布式系统中常用的一致性协议:
| 协议 | 特点 |
|---|---|
| Paxos | 理论基础,难以理解和实现 |
| Raft | 易于理解的共识算法(Consul、etcd 采用) |
| ZAB | ZooKeeper 采用的原子广播协议 |
Paxos 算法是 Leslie Lamport 在 1990 年提出的一种基于消息传递的一致性算法,非常难以理解。基于 Paxos 协议的数据同步与传统主备方式最大的区别在于:Paxos 只需超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。
Raft 是斯坦福大学的 Diego Ongaro、John Ousterhout 以易理解为目标设计的一致性算法,已经有了十几种语言的实现框架,较为出名的有 etcd,Google 的 Kubernetes 也使用了 etcd 作为服务发现框架。Raft 是 Paxos 的简化版,强调易理解、易实现,和 Paxos 一样只要保证超过半数的节点正常就能够提供服务。
ZAB(ZooKeeper Atomic Broadcast,ZooKeeper 原子消息广播协议)是 ZooKeeper 实现分布式数据一致性的核心算法,借鉴了 Paxos 算法,但不同于 Paxos 作为一种通用的分布式一致性算法,ZAB 是特别为 ZooKeeper 设计的支持崩溃恢复的原子广播协议。
五种注册中心对比
1. ZooKeeper
- CAP:CP(保证一致性)
- 语言:Java
- 应用场景:Dubbo 生态、Hadoop、Kafka
- 特点:功能强大(不仅是注册中心,还是分布式协调器),但重量级
国内 Dubbo 场景下大量使用 ZooKeeper 来完成注册中心功能。ZooKeeper 可以充当服务注册表(Service Registry),让多个服务提供者形成一个集群,让服务消费者通过注册表获取具体的服务访问地址(IP + 端口)去访问具体的服务提供者。
ZooKeeper 不适合作为注册中心:作为一个分布式协同服务,ZooKeeper 非常好,但对于 Service 发现服务来说就不合适了。因为对于服务发现来说,即使返回了包含不实信息的结果也比什么都不返回要好——我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接 down 掉不可用。
当 master 节点因网络故障与其他节点失去联系时,剩余节点会重新进行 leader 选举。选举时间太长(30 ~ 120s),且选举期间整个 zk 集群都不可用,导致注册服务瘫痪。在云部署环境下,因网络问题使 zk 集群失去 master 节点是较大概率发生的事。作为注册中心,可用性的要求要高于一致性。
在 CAP 模型中,ZooKeeper 整体遵循 CP 原则,即在任何时候对 ZooKeeper 的访问请求能得到一致的数据结果,但机器下线或宕机时不能保证服务可用性。这是因为 ZooKeeper 的核心算法是 ZAB,所有设计都是为了强一致性——对分布式协调系统完全没问题,但用在注册中心或服务发现场景就不合适了。
2. Eureka
- CAP:AP(保证可用性)
- 语言:Java
- 应用场景:Spring Cloud 生态
- 特点:自我保护机制,不会因网络问题剔除所有实例;Netflix 已停止维护 1.x 版本
Eureka 在设计时紧遵 AP 原则,集群中只要有一台 Eureka 还在,就能保证注册服务可用,只不过查到的信息可能不是最新的。
核心特点:
- 去中心化架构:Eureka Server 采用 Peer to Peer 对等通信,无 master/slave 之分,每个 Peer 都是对等的,节点通过彼此互相注册来提高可用性
- 请求自动切换:集群中某台 Eureka Server 宕机时,Client 的请求会自动切换到新的节点
- 节点间操作复制:所有操作都会在节点间复制,将请求复制到当前所知的其它所有节点
- 自动注册和心跳:新节点启动后从邻近节点获取注册列表并完成初始化,通过心跳契约定期更新
- 自动下线:默认 30 秒心跳周期,90 秒未收到心跳则注销实例
- 保护模式:15 分钟内超过 85% 的节点没有正常心跳时,进入自我保护——不再移除过期服务,仍接受新注册和查询但不同步到其它节点,网络恢复后自动退出保护模式
3. Nacos
- CAP:AP + CP(可切换)
- 语言:Java
- 应用场景:Spring Cloud、Dubbo 生态
- 特点:阿里巴巴开源,同时支持 AP 和 CP 模式切换,集配置中心和服务发现于一体
Nacos 致力于帮助发现、配置和管理微服务,提供了一组简单易用的特性集,帮助快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 主要特点:
- 服务发现和健康监测:支持基于 DNS 和 RPC 的服务发现,提供实时健康检查,支持传输层(PING/TCP)和应用层(HTTP、MySQL、自定义)的健康检查,提供 agent 上报和服务端主动检测两种模式
- 动态配置服务:中心化、外部化和动态化的配置管理,消除配置变更时重新部署的需要,提供配置版本跟踪、金丝雀发布、一键回滚等特性
- 动态 DNS 服务:支持权重路由,更容易实现中间层负载均衡、灵活的路由策略和流量控制
Nacos 的注册中心支持 CP 也支持 AP,只是一个命令的切换。除了服务注册发现之外还支持动态配置服务,可以概括为 Nacos = Spring Cloud 注册中心 + Spring Cloud 配置中心。
4. Consul
- CAP:CP(Raft 协议保证一致性)
- 语言:Go
- 应用场景:多语言微服务架构
- 特点:内置健康检查、KV 存储、多数据中心支持、提供 Web UI
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul 的方案更"一站式",内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具。
特性:
- CP 模型,使用 Raft 算法保证强一致性,不保证可用性
- 服务发现:支持通过 DNS 和 HTTP 查询服务地址,可以为服务生成和分发 TLS 证书
- 健康检查:定时监控服务是否正常,异常服务主动下线
- 键值存储:key/value 存储结构,key 以目录树形式组织,用于存储系统配置信息
- 官方提供 Web 管理界面
- 多数据中心:支持多数据中心部署
工作流程:
- Producer 启动时向 Consul 发送 POST 请求,告知 IP 和 Port
- Consul 每隔 10s(默认)向 Producer 发送健康检查请求
- Consumer 请求时先从 Consul 获取临时表(存储服务 IP 和 Port),拿到 Producer 地址后发起调用
- 临时表每隔 10s 更新,只包含通过健康检查的 Producer
架构:Consul 是分布式、高可用的系统。主要有 Server 和 Client 两种组件。Server 负责核心数据的存储和处理请求,可以部署多个实例(推荐 3-5 个),只有一个 Leader 实例负责处理数据写入并同步到其它 Server 节点。Client 负责跟 Server 通信、转发请求,还负责服务的健康检查,每个微服务节点都可以部署一个 Client 实例。
集群内 Consul 节点通过 gossip 协议(流言协议)维护成员关系,集群内使用 TCP 和 UDP 的 8301 端口,跨数据中心使用 8302 端口。数据的读写和复制通过 TCP 的 8300 端口完成。
5. etcd
- CAP:CP(Raft 协议保证一致性)
- 语言:Go
- 应用场景:Kubernetes 核心(存储集群状态)
- 特点:轻量级,KV 存储,适合作为配置中心和注册中心
etcd 是 Go 语言编写的分布式、高可用的一致性键值存储系统,用于提供可靠的分布式键值存储、配置共享和服务发现等功能。
特点:
- 易使用:基于 HTTP + JSON 的 API,用 curl 就可以轻松使用
- 易部署:Go 语言编写,跨平台,部署和维护简单
- 强一致:使用 Raft 算法充分保证分布式系统数据的强一致性
- 高可用:假设集群有 n 个节点,当有 (n-1)/2 节点故障时仍能提供服务
- 持久化:数据更新后通过 WAL 格式持久化到磁盘,支持 Snapshot 快照
- 快速:每个实例每秒支持一千次写操作,极限写性能可达 10K QPS
- 安全:可选 SSL 客户认证机制
- etcd 3.0:支持 gRPC 通信、watch 机制
主要分为四个部分:
- HTTP Server:处理用户 API 请求以及其它 etcd 节点的同步与心跳信息请求
- Store:处理各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理等
- Raft:Raft 强一致性算法的具体实现,是 etcd 的核心
- WAL:Write Ahead Log(预写式日志),所有数据提交前都会事先记录日志
综合对比表
| 特性 | ZooKeeper | Eureka | Nacos | Consul | etcd |
|---|---|---|---|---|---|
| CAP | CP | AP | AP/CP | CP | CP |
| 一致性协议 | ZAB | — | Raft/Distro | Raft | Raft |
| 健康检查 | 长连接 | 心跳 | 心跳/HTTP/TCP | HTTP/TCP/gRPC | HTTP |
| KV 存储 | 是 | 否 | 是 | 是 | 是 |
| 多数据中心 | 否 | 否 | 是 | 是 | 否 |
| Web UI | 需第三方 | 有 | 有 | 有 | 需第三方 |
| 语言 | Java | Java | Java | Go | Go |
| Spring Cloud 集成 | 一般 | 好 | 好 | 好 | 一般 |
选型建议
| 场景 | 推荐 |
|---|---|
| Java/Spring Cloud 体系 | Nacos(功能全面)或 Eureka(简单) |
| 多语言微服务 | Consul(原生支持多语言客户端) |
| Kubernetes 环境 | etcd(K8s 内置)或 Consul |
| 已有 Dubbo 体系 | ZooKeeper 或 Nacos |
| Node.js/NestJS 微服务 | Consul(轻量、Go 编写、gRPC 健康检查) |
本课程选择 Consul 作为注册中心,因为它轻量、支持多语言、内置健康检查、有 Web 管理界面,适合 Node.js 微服务架构。
↑